# -*- coding: utf-8 -*-
import sys
from PySide6.QtGui import QPixmap, QImage, QShortcut, QKeySequence
from PySide6.QtCore import Qt
import qrcode
from qrcode.constants import ERROR_CORRECT_M
import zxingcpp
import io
import numpy as np

from PySide6.QtWidgets import (
    QApplication,
    QWidget,
    QTabWidget,
    QVBoxLayout,
    QHBoxLayout,
    QPushButton,
    QLabel,
    QTextEdit,
    QFileDialog,
    QLineEdit,
)


class QRDecodeTab(QWidget):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout(self)

        # 图片展示框
        self.image_label = QLabel("请选择图片")
        self.image_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.image_label.setFixedHeight(200)
        layout.addWidget(self.image_label)

        # 选择图片按钮
        btn_layout = QHBoxLayout()
        self.select_btn = QPushButton("选择图片")
        self.select_btn.clicked.connect(self.select_image)
        btn_layout.addStretch()
        btn_layout.addWidget(self.select_btn)
        btn_layout.addStretch()
        layout.addLayout(btn_layout)

        # 解析结果展示框
        self.result_text = QTextEdit()
        self.result_text.setReadOnly(True)
        layout.addWidget(self.result_text)

        # 复制按钮
        copy_layout = QHBoxLayout()
        self.copy_btn = QPushButton("复制结果")
        self.copy_btn.clicked.connect(self.copy_result)
        copy_layout.addStretch()
        copy_layout.addWidget(self.copy_btn)
        copy_layout.addStretch()
        layout.addLayout(copy_layout)

    def copy_result(self):
        text = self.result_text.toPlainText()
        if text:
            clipboard = QApplication.clipboard()
            clipboard.setText(text)

    def select_image(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择图片", "", "Images (*.png *.jpg *.jpeg *.bmp)"
        )
        if file_path:
            pixmap = QPixmap(file_path)
            self.image_label.setPixmap(
                pixmap.scaled(
                    self.image_label.size(),
                    Qt.AspectRatioMode.KeepAspectRatio,
                    Qt.TransformationMode.SmoothTransformation,
                )
            )
            # 解析二维码
            buffer = self.image_label.pixmap().toImage()
            # 将 QImage 转为 numpy 数组
            ptr = buffer.bits()

            width = buffer.width()
            height = buffer.height()
            # ptr.setsize(buffer.byteCount())
            arr = np.array(ptr).reshape((height, width, buffer.depth() // 8))

            # zxingcpp 需要灰度或RGB图像
            if arr.shape[2] == 4:
                arr = arr[:, :, :3]  # 去除 alpha 通道
            result = zxingcpp.read_barcodes(arr)
            if result:
                texts = [barcode.text for barcode in result if barcode.text]
                self.result_text.setPlainText(
                    "\n".join(texts) if texts else "未识别到二维码"
                )
            else:
                self.result_text.setPlainText("未识别到二维码")
        else:
            self.image_label.setText("请选择图片")
            self.result_text.clear()


class QREncodeTab(QWidget):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout(self)

        # 文字输入框
        self.input_edit = QLineEdit()
        self.input_edit.setPlaceholderText("请输入要生成二维码的内容")
        layout.addWidget(self.input_edit)

        # 生成按钮
        btn_layout = QHBoxLayout()
        self.gen_btn = QPushButton("生成二维码")
        self.gen_btn.clicked.connect(self.generate_qr)
        btn_layout.addStretch()
        btn_layout.addWidget(self.gen_btn)
        btn_layout.addStretch()
        layout.addLayout(btn_layout)

        # 二维码展示框
        self.qr_label = QLabel()
        self.qr_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.qr_label.setFixedHeight(200)
        layout.addWidget(self.qr_label)

        # 保存按钮
        save_layout = QHBoxLayout()
        self.save_btn = QPushButton("保存二维码")
        self.save_btn.clicked.connect(self.save_qr)
        self.save_btn.setEnabled(False)
        save_layout.addStretch()
        save_layout.addWidget(self.save_btn)
        save_layout.addStretch()
        layout.addLayout(save_layout)

        self.qr_img = None

    def generate_qr(self):
        text = self.input_edit.text().strip()
        if not text:
            self.qr_label.setText("请输入内容")
            self.save_btn.setEnabled(False)
        qr = qrcode.QRCode(error_correction=ERROR_CORRECT_M)
        qr.add_data(text)
        qr.make(fit=True)
        img = qr.make_image(fill_color="black", back_color="white")
        buf = io.BytesIO()
        img.save(buf)
        buf.seek(0)
        qimg = QImage.fromData(buf.read())
        self.qr_label.setPixmap(
            QPixmap.fromImage(qimg).scaled(
                self.qr_label.size(),
                Qt.AspectRatioMode.KeepAspectRatio,
                Qt.TransformationMode.SmoothTransformation,
            )
        )
        self.qr_img = img
        self.save_btn.setEnabled(True)

    def save_qr(self):
        if self.qr_img:
            file_path, _ = QFileDialog.getSaveFileName(
                self, "保存二维码", "", "PNG Image (*.png)"
            )
            if file_path:
                buf = io.BytesIO()
                self.qr_img.save(buf)
                with open(file_path, "wb") as f:
                    f.write(buf.getvalue())
                self.qr_label.setText("二维码已保存")
            else:
                self.qr_label.setText("保存失败，请重试")


class QRCodePanel(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("二维码工具")
        self.resize(400, 400)
        layout = QVBoxLayout(self)
        tabs = QTabWidget()
        tabs.addTab(QRDecodeTab(), "解析二维码")
        tabs.addTab(QREncodeTab(), "生成二维码")
        layout.addWidget(tabs)

        # 添加快捷键Esc退出程序
        QShortcut(QKeySequence("Esc"), self, self.close)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = QRCodePanel()
    win.show()
    sys.exit(app.exec())
